package com.cskaoyan.service.wx.impl;

import com.cskaoyan.bean.pojo.*;
import com.cskaoyan.bean.pojo.System;
import com.cskaoyan.bean.wx.order.bo.AddOrderBo;
import com.cskaoyan.bean.wx.order.bo.CommentBo;
import com.cskaoyan.bean.wx.order.bo.PageInfoBo;
import com.cskaoyan.bean.wx.order.vo.*;
import com.cskaoyan.mapper.*;
import com.cskaoyan.service.wx.WxOrderService;
import com.cskaoyan.util.GetUserIdUtils;
import com.cskaoyan.util.OrderStatusEnum;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Name : WxOrderServiceImpl.java
 * @Time : 2021/8/15 14:44
 * @Author : Xfeng
 * @Software : IntelliJ IDEA
 */

@Service
@Transactional
public class WxOrderServiceImpl implements WxOrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private GrouponMapper grouponMapper;

    @Autowired
    private OrderGoodsMapper orderGoodsMapper;

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private AddressMapper addressMapper;

    @Autowired
    private RegionMapper regionMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private SystemMapper systemMapper;

    @Autowired
    private CouponUserMapper couponUserMapper;

    @Autowired
    private CouponMapper couponMapper;


    @Override
    public OrderListVo list(Integer showType, PageInfoBo pageInfoBo) {
        Integer currentUserId = GetUserIdUtils.getCurrentUserId(userMapper);

        //分页
        PageHelper.startPage(pageInfoBo.getPage(), pageInfoBo.getSize());

        //构建查询条件
        OrderExample orderExample = new OrderExample();
        orderExample.setOrderByClause("add_time desc");
        OrderExample.Criteria criteria = orderExample.createCriteria();
        criteria.andDeletedEqualTo(false);
        criteria.andUserIdEqualTo(currentUserId);
        if (showType != null && !showType.equals("") && showType != 0) {
            if (showType == 1) {
                //待付款
                criteria.andOrderStatusEqualTo(new Short("101"));
            } else if (showType == 2) {
                //待发货
                criteria.andOrderStatusEqualTo(new Short("201"));
            } else if (showType == 3) {
                //待收货
                criteria.andOrderStatusEqualTo(new Short("301"));
            } else if (showType == 4) {
                criteria.andOrderStatusBetween(new Short("400"), new Short("500")).andCommentsGreaterThan(new Short("0"));
            }
        }
        List<Order> orders = orderMapper.selectByExample(orderExample);

        //封装
        List<OrderVo> orderVos = new ArrayList<>();
        for (Order order : orders) {
            OrderVo orderVo = new OrderVo();

            //setStatusText
            Integer orderStatus = Integer.parseInt("" + order.getOrderStatus());
            OrderStatusEnum[] values = OrderStatusEnum.values();
            for (OrderStatusEnum value : values) {
                if (orderStatus.equals(value.getStateId())) {
                    orderVo.setOrderStatusText(value.getStateName());
                }
            }

            //setHandleOption
            HandleOptionVo handleOptionVo = getHandleOption(order);
            orderVo.setHandleOption(handleOptionVo);

            GrouponExample grouponExample = new GrouponExample();
            grouponExample.createCriteria().andDeletedEqualTo(false).andOrderIdEqualTo(order.getId());
            if (grouponMapper.countByExample(grouponExample) != 0) {
                orderVo.setIsGroupin(true);
            }

            orderVo.setOrderSn(order.getOrderSn());
            orderVo.setId(order.getId());
            orderVo.setActualPrice(order.getActualPrice());

            OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
            orderGoodsExample.createCriteria().andDeletedEqualTo(false).andOrderIdEqualTo(order.getId());
            List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(orderGoodsExample);
            ArrayList<OrderVo.GoodsListEntity> goodsListEntities = new ArrayList<>();
            for (OrderGoods orderGood : orderGoods) {
                OrderVo.GoodsListEntity goodsListEntity = new OrderVo().new GoodsListEntity(orderGood.getNumber(), orderGood.getPicUrl(), orderGood.getId(), orderGood.getGoodsName());
                goodsListEntities.add(goodsListEntity);
            }
            orderVo.setGoodsList(goodsListEntities);

            orderVos.add(orderVo);
        }
        PageInfo<Order> orderPageInfo = new PageInfo<>(orders);
        OrderListVo orderListVo = new OrderListVo(orderVos, orderPageInfo.getTotal(), orderPageInfo.getPages());
        return orderListVo;
    }

    private HandleOptionVo getHandleOption(Order order) {
        Integer orderStatus = Integer.parseInt("" + order.getOrderStatus());
        HandleOptionVo handleOptionVo = new HandleOptionVo();
        if (orderStatus.equals(OrderStatusEnum.UNPAID.getStateId())) {
            handleOptionVo.setCancel(true);
            handleOptionVo.setPay(true);
        } else if (orderStatus.equals(OrderStatusEnum.CANCELED_BY_SYSTEM.getStateId()) || orderStatus.equals(OrderStatusEnum.CANCELED_BY_USER.getStateId()) || orderStatus.equals(OrderStatusEnum.REFUNDED.getStateId())) {
            handleOptionVo.setDelete(true);
        } else if (orderStatus.equals(OrderStatusEnum.PAID.getStateId())) {
            handleOptionVo.setRefund(true);
        } else if (orderStatus.equals(OrderStatusEnum.DELIVERED.getStateId())) {
            handleOptionVo.setConfirm(true);
            handleOptionVo.setRefund(true);
        } else if (orderStatus.equals(OrderStatusEnum.CONFIRM_BY_USER.getStateId()) || orderStatus.equals(OrderStatusEnum.CONFIRM_BY_SYSTEM.getStateId())) {
            handleOptionVo.setRefund(true);
            handleOptionVo.setDelete(true);
            handleOptionVo.setRebuy(true);
            if (!order.getComments().equals(new Short("0"))) {
                handleOptionVo.setComment(true);
            }
        }
        return handleOptionVo;
    }


    @Override
    public OrderDetailVo detail(Integer orderId) {
        Order order = orderMapper.selectByPrimaryKey(orderId);
        OrderDetailVo orderDetailVo = new OrderDetailVo();
        OrderDetailVo.OrderInfoEntity orderInfoEntity = orderDetailVo.new OrderInfoEntity(null, order.getConsignee(), order.getAddress(), order.getAddTime(), order.getOrderSn(), order.getActualPrice(), order.getGoodsPrice(), order.getMobile(), order.getCouponPrice(), order.getId(), order.getFreightPrice(), null);
        //setStatusText
        Integer orderStatus = Integer.parseInt("" + order.getOrderStatus());
        OrderStatusEnum[] values = OrderStatusEnum.values();
        for (OrderStatusEnum value : values) {
            if (orderStatus.equals(value.getStateId())) {
                orderInfoEntity.setOrderStatusText(value.getStateName());
            }
        }
        //setHandleOption
        HandleOptionVo handleOption = getHandleOption(order);
        orderInfoEntity.setHandleOption(handleOption);

        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        orderGoodsExample.createCriteria().andDeletedEqualTo(false).andOrderIdEqualTo(order.getId());
        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(orderGoodsExample);

        orderDetailVo.setOrderInfo(orderInfoEntity);
        orderDetailVo.setOrderGoods(orderGoods);

        return orderDetailVo;
    }

    @Override
    public void cancel(OrderGoods orderGoods) {
        Integer id = orderGoods.getOrderId();
        Order order = new Order();
        order.setId(id);
        order.setOrderStatus(new Short("" + OrderStatusEnum.CANCELED_BY_USER.getStateId()));
        Date date = new Date();
        order.setUpdateTime(date);
        order.setEndTime(date);
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public void refund(OrderGoods orderGoods) {
        Integer id = orderGoods.getOrderId();
        Order order = new Order();
        order.setId(id);
        order.setOrderStatus(new Short("" + OrderStatusEnum.REFUNDING.getStateId()));
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public void delete(OrderGoods orderGoods) {
        Integer id = orderGoods.getOrderId();
        Order order = new Order();
        order.setId(id);
        order.setDeleted(true);
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public void confirm(OrderGoods orderGoods) {
        Integer id = orderGoods.getOrderId();
        Order order = new Order();
        order.setId(id);
        order.setOrderStatus(new Short("" + OrderStatusEnum.CONFIRM_BY_USER.getStateId()));
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public OrderGoods goods(Integer orderId, Integer goodsId) {
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        orderGoodsExample.createCriteria().andDeletedEqualTo(false).andOrderIdEqualTo(orderId).andGoodsIdEqualTo(goodsId);
        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(orderGoodsExample);//取出来的应该只有一个
        return orderGoods.get(0);
    }

    @Override
    public void comment(CommentBo commentBo) {
        OrderGoods orderGoods = orderGoodsMapper.selectByPrimaryKey(commentBo.getOrderGoodsId());
        Date date = new Date();
        Integer currentUserId = GetUserIdUtils.getCurrentUserId(userMapper);
        Comment comment = new Comment(null, orderGoods.getGoodsId(), new Byte("0"), commentBo.getContent(), currentUserId, commentBo.getHasPicture(), commentBo.getPicUrls(), new Short("" + commentBo.getStar()), date, date, false);
        commentMapper.insertSelective(comment);
        OrderGoods orderGoods1 = new OrderGoods();
        orderGoods1.setId(commentBo.getOrderGoodsId());
        orderGoods1.setComment(comment.getId());
        orderGoods1.setUpdateTime(date);
        orderGoodsMapper.updateByPrimaryKeySelective(orderGoods1);
        Order order = new Order();
        order.setId(orderGoods.getOrderId());
        Short comments = orderMapper.selectByPrimaryKey(orderGoods.getOrderId()).getComments();
        order.setComments(new Short("" + (comments - new Short("1"))));
        order.setUpdateTime(date);
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public OrderIdVo submit(AddOrderBo addOrderBo) {
        //获取用户ID
        Integer userId = GetUserIdUtils.getCurrentUserId(userMapper);

        //查address相关 地址拼接
        Address address = addressMapper.selectByPrimaryKey(addOrderBo.getAddressId());
        Integer provinceId = address.getProvinceId();
        Integer cityId = address.getCityId();
        Integer areaId = address.getAreaId();
        String province = regionMapper.selectByPrimaryKey(provinceId).getName();
        String city = regionMapper.selectByPrimaryKey(cityId).getName();
        String area = regionMapper.selectByPrimaryKey(areaId).getName();
        String add = province + " " + city + " " + area + " " + address.getAddress();

        //goods_price
        BigDecimal goodsPrice = new BigDecimal(0);
        //comments
        int goodsNumber = 0;

        List<Cart> cartList = null;
        Cart singleCart = null;

        //判断cartId是否为0
        if (addOrderBo.getCartId() == 0) {
            //多个商品
            CartExample cartExample = new CartExample();
            cartExample.createCriteria().andDeletedEqualTo(false).andUserIdEqualTo(userId).andCheckedEqualTo(true);
            cartList = cartMapper.selectByExample(cartExample);
            for (Cart cart : cartList) {
                goodsPrice = goodsPrice.add(cart.getPrice().multiply(BigDecimal.valueOf(cart.getNumber())));
                goodsNumber += 1;
            }
        } else {
            //一个商品
            singleCart = cartMapper.selectByPrimaryKey(addOrderBo.getCartId());
            goodsPrice = singleCart.getPrice().multiply(BigDecimal.valueOf(singleCart.getNumber()));
            goodsNumber = 1;
        }

        //根据system表查出包邮额度及运费等信息
        List<Map<String, String>> systemMap = systemMapper.selectKeyAndValue();
        BigDecimal expressFreightMin = new BigDecimal(0);
        BigDecimal expressFreightValue = new BigDecimal(0);

        for (Map<String, String> stringStringMap : systemMap) {

            if ("cskaoyan_mall_express_freight_min".equals(stringStringMap.get("key_name"))) {
                expressFreightMin = BigDecimal.valueOf(Double.parseDouble(stringStringMap.get("key_value")));
            }
            if ("cskaoyan_mall_express_freight_value".equals(stringStringMap.get("key_name"))) {
                expressFreightValue = BigDecimal.valueOf(Double.parseDouble(stringStringMap.get("key_value")));
            }
        }

        //freight_price
        //如果商品总价超过免运费额度 则 运费为0  反之为运费为value
        BigDecimal freightPrice = new BigDecimal(0);
        if (goodsPrice.compareTo(expressFreightMin) < 0) {
            freightPrice = expressFreightValue;
        }

        Coupon coupon = couponMapper.selectByPrimaryKey(addOrderBo.getCouponId());
        //coupon_price
        BigDecimal couponPrice = new BigDecimal(0);
        if(coupon != null){
            couponPrice =  coupon.getDiscount();
        }
        //integral_price
        BigDecimal integralPrice = new BigDecimal(0);
        //groupon_price
        BigDecimal grouponPrice = new BigDecimal(0);
        //order_price
        BigDecimal orderPrice = goodsPrice.add(freightPrice).subtract(couponPrice);
        //actual_price
        BigDecimal actualPrice = orderPrice.subtract(integralPrice);

        Date date = new Date();
        String format = new SimpleDateFormat("yyyyMMddHHmmss").format(date);

        //插入到order表中
        Order order = new Order(null, userId, format, new Short("" + OrderStatusEnum.UNPAID.getStateId()), address.getName(), address.getMobile(), add, addOrderBo.getMessage(), goodsPrice, freightPrice, couponPrice, integralPrice, grouponPrice, orderPrice, actualPrice, null, null, null, null, null, null, (short) goodsNumber, null, date, date, false);
        orderMapper.insertSelective(order);

        //插入到order_goods表
        //清空购物车
        if (cartList != null) {//多个商品
            for (Cart cart : cartList) {
                OrderGoods orderGoods = new OrderGoods(null, order.getId(), cart.getGoodsId(), cart.getGoodsName(), cart.getGoodsSn(), cart.getProductId(), cart.getNumber(), cart.getPrice(), Arrays.toString(cart.getSpecifications()), cart.getPicUrl(), 0, date, date, false);
                orderGoodsMapper.insertSelective(orderGoods);
                cart.setDeleted(true);
                cartMapper.updateByPrimaryKey(cart);
            }
        } else {//单个商品
            String[] specifications = singleCart.getSpecifications();
            OrderGoods orderGoods = new OrderGoods(null, order.getId(), singleCart.getGoodsId(), singleCart.getGoodsName(), singleCart.getGoodsSn(), singleCart.getProductId(), singleCart.getNumber(), singleCart.getPrice(), Arrays.toString(specifications), singleCart.getPicUrl(), 0, date, date, false);
            orderGoodsMapper.insertSelective(orderGoods);
            singleCart.setDeleted(true);
            cartMapper.updateByPrimaryKey(singleCart);
        }

        //更改优惠券状态
        CouponUserExample couponUserExample = new CouponUserExample();
        couponUserExample.createCriteria().andUserIdEqualTo(userId).andCouponIdEqualTo(addOrderBo.getCouponId()).andDeletedEqualTo(false);
        List<CouponUser> couponUsers = couponUserMapper.selectByExample(couponUserExample);
        if(couponUsers.size() >= 1){
            CouponUser couponUser = new CouponUser(couponUsers.get(0).getId(), null, null, new Short("1"), date, null, null, order.getId(), null, date, null);
            couponUserMapper.updateByPrimaryKeySelective(couponUser);
        }

        return new OrderIdVo(order.getId());
    }

    @Override
    public void prepay(OrderIdVo orderIdVo) {
//        System unpaidValue = systemMapper.selectByPrimaryKey(33);
//        systemMapper.updateUnpaidValue((Integer.parseInt(unpaidValue.getKeyValue()) + 1));
        Integer id = orderIdVo.getOrderId();
        Order order = new Order();
        order.setId(id);
        order.setOrderStatus(new Short("" + OrderStatusEnum.PAID.getStateId()));
        Date date = new Date();
        order.setUpdateTime(date);
        order.setPayTime(date);
        orderMapper.updateByPrimaryKeySelective(order);
    }
}
